import java.util.*;

class Person {
    private final String name;
    private final int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /* 1. 只重写 hashCode - 故意不重写 equals */
    @Override
    public int hashCode() {
        // 经典配方：字段哈希累加
        return Objects.hash(name, age);
        
        // 另一种写法：
        // int h = 0;
        // h = 31 * h + name.hashCode();
        // h = 31 * h + age;
        // return h;
    }

    /* 2. 再补 equals - 保持同 hashCode 语义一致 */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person p = (Person) o;
        return age == p.age && Objects.equals(name, p.name);
    }
}

public class Test {
    public static void main(String[] args) {
        Map<Person, String> map = new HashMap<>();

        Person p1 = new Person("Alice", 20);
        Person p2 = new Person("Alice", 20);   // 内容完全一样

        map.put(p1, "A");
        System.out.println("map大小 = " + map.size()); // 1

        /* 3. 只重写 hashCode 时 - 查找失败 */
        System.out.println("用 p2 查找结果 = " + map.get(p2)); // null（找不到）

        /* 4. 放开 equals 后 - 查找成功 */
        System.out.println("补 equals 后结果 = " + map.get(p2)); // A
    }
}

// HashMap 先按 hashCode 定位桶，再用 equals 判同桶内元素是否相等；
// 只重写 hashCode 不重写 equals → 同内容对象也插/查失败；
// 必须成对重写！